package cl.jpavlich.mpm.view.metawidgets;
import static org.metawidget.inspector.InspectionResultConstants.HIDDEN;
import static org.metawidget.inspector.InspectionResultConstants.LOOKUP;
import static org.metawidget.inspector.InspectionResultConstants.NAME;
import static org.metawidget.inspector.InspectionResultConstants.PARAMETERIZED_TYPE;
import static org.metawidget.inspector.InspectionResultConstants.TRUE;
import static org.metawidget.inspector.InspectionResultConstants.TYPE;

import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import org.metawidget.swing.SwingMetawidget;
import org.metawidget.util.ClassUtils;
import org.metawidget.util.CollectionUtils;
import org.metawidget.util.XmlUtils;
import org.metawidget.widgetbuilder.iface.WidgetBuilder;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cl.jpavlich.mpm.view.EditDialog;


public class CollectionWidgetBuilder implements
		WidgetBuilder<JComponent, SwingMetawidget> {

	public JComponent buildWidget(String elementName,
			Map<String, String> attributes, SwingMetawidget metawidget) {

		// Not for us?

		if (TRUE.equals(attributes.get(HIDDEN))
				|| attributes.containsKey(LOOKUP)) {
			return null;
		}

		String type = attributes.get(TYPE);

		if (type == null || "".equals(type)) {
			return null;
		}

		final Class<?> clazz = ClassUtils.niceForName(type);

		if (clazz == null) {
			return null;
		}

		if (!Collection.class.isAssignableFrom(clazz)) {
			return null;
		}

		// Inspect type of List

		String componentType = attributes.get(PARAMETERIZED_TYPE);
		String inspectedType = metawidget.inspect(null, componentType,
				(String[]) null);

		// Determine columns

		List<String> columns = CollectionUtils.newArrayList();
		Element root = XmlUtils.documentFromString(inspectedType)
				.getDocumentElement();
		NodeList elements = root.getFirstChild().getChildNodes();

		for (int loop = 0, length = elements.getLength(); loop < length; loop++) {

			Node node = elements.item(loop);
			if (!"action".equals (node.getNodeName())) {
				columns.add(metawidget.getLabelString(XmlUtils
					.getAttributesAsMap(node)));
			}
		}

		// Fetch the data. This part could be improved to use BeansBinding or
		// similar

		Collection<?> list = (Collection<?>) ClassUtils.getProperty(
				metawidget.getToInspect(), attributes.get(NAME));
		Method m = ClassUtils.getReadMethod(metawidget.getToInspect().getClass(), attributes.get(NAME));
		Type t = m.getGenericReturnType();
		Class<?> elementType;
		if (t instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) t;
			elementType = (Class<?>) pt.getActualTypeArguments()[0];
		} else {
			elementType = Object.class;
		}

		// Return the JTable

		@SuppressWarnings({ "unchecked", "rawtypes" })
		final ListTableModel<?> tableModel = new ListTableModel(elementType, new ArrayList(list),  columns.toArray(new String[]{}));
		JPanel panel = new JPanel();
		final JTable table = new JTable(tableModel);
		table.addMouseListener(new MouseListener() {

			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			public void mouseClicked(MouseEvent e) {
				Object obj = tableModel.getValueAt(table.getSelectedRow());
				EditDialog ew = new EditDialog();
				ew.edit(obj);
			}
		});

		panel.setLayout(new GridBagLayout());
		panel.add(new JScrollPane(table));
		JButton buttonAdd = new JButton("Add");
		buttonAdd.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		
		return panel;
	}
	
//	public SwingMetawidget createMetaWidget(Object obj) {
//		SwingMetawidget metawidget = new SwingMetawidget();
//		CompositeInspectorConfig inspectorConfig = new CompositeInspectorConfig()
//				.setInspectors(new PropertyTypeInspector(),
//						new MetawidgetAnnotationInspector(),
//						new Java5Inspector());
//		metawidget.setInspector(new CompositeInspector(inspectorConfig));
//
//		metawidget.setToInspect(obj);
//		return metawidget;
//	}
}
